package com.seed.core.query;

import com.seed.core.action.Action;
import com.seed.core.pojo.seed.Seed;
import com.seed.util.ThrowKit;

import java.util.Map;

public class Micro {

    private Map<String, Seed> seeds;
    private Map<String, Action> actions;

    public Micro() {}

    public Micro(Map<String, Seed> seeds, Map<String, Action> actions) {
        this.seeds = seeds;
        this.actions = actions;
    }

    public Seed getSeed(String seedName) {
        if(seeds == null) return null;

        Seed seed = seeds.get(seedName);
        if(seed == null) ThrowKit.exception("元数据【%s】不存在", seedName);

        return seed;
    }

    public Map<String, Seed> getSeeds() {
        return seeds;
    }

    public void setSeeds(Map<String, Seed> seeds) {
        this.seeds = seeds;
    }

    public Map<String, Action> getActions() {
        return actions;
    }

    public void setActions(Map<String, Action> actions) {
        this.actions = actions;
    }

//    public String getTableName(String seedName) {
//        return getTableName(getSeed(seedName));
//    }
//
//    public static String getTableName(Seed seed) {
//        String tableName = seed.getTableName();
//        if(StrUtil.isBlank(tableName)) throw new RuntimeException(String.format("请在【%s】下配置tableName的值", seed.getName()));
//
//        return tableName;
//    }

//    public String getLabel(String seedName) {
//        return SeedKit.getLabel(getSeed(seedName));
//    }

//    public Map<String, Action> getActions(String seedName) {
//        return SeedKit.getActions(getSeed(seedName));
//    }

//    public Action getAction(String seedName, RequestMethod method, String actionName) {
//        return SeedKit.getAction(getSeed(seedName), method, actionName);
//    }

//    public Action getAction(RequestMethod method, String actionName) {
//        if(actions == null) return null;
//
//        Action action = actions.get(actionName);
//        if(action == null || action.getMethods() == null) return null;
//
//        return action.getMethods().contains(method) ? action : null;
//    }

//    public List<String> getDeclares(String seedName, RequestMethod method, String actionName) {
//        return SeedKit.getDeclares(getSeed(seedName), method, actionName);
//    }
//
//    public List<String> getDeclares(RequestMethod method, String actionName) {
//        Action action = getAction(method, actionName);
//        if(action == null) {
//            throw new RuntimeException(String.format("【%s】不存在", actionName));
//        }
//
//        return getDeclares(action);
//    }

//    public List<String> getDeclares(Action action) {
//        if(action == null) throw new RuntimeException("【action】不能为空");
//
//        String seedName = action.getSeedName();
//        if(StrUtil.isBlank(seedName)) return Collections.emptyList();
//
//        // 带路径的配置
//        List<String> declares = action.getDeclares();
//        if(declares != null) return declares;
//
//        Seed seed = getSeed(seedName);
//        declares = seed.getDeclares();
//        if(declares != null) return declares;
//
//        return SeedKit.getDefaultDeclares(seed);
//    }
//
//    public List<String> getSearches(String seedName, RequestMethod method, String actionName) {
//        return SeedKit.getSearches(getSeed(seedName), method, actionName);
//    }
//
//    public List<String> getSearches(RequestMethod method, String actionName) {
//        Action action = getAction(method, actionName);
//        if(action == null) {
//            throw new RuntimeException(String.format("【%s】不存在", actionName));
//        }
//
//        return getSearches(action);
//    }
//
//    public List<String> getSearches(Action action) {
//        if(action == null) throw new RuntimeException("【action】不能为空");
//
//        String seedName = action.getSeedName();
//        if(StrUtil.isBlank(seedName)) return Collections.emptyList();
//
//        // 带路径的配置
//        List<String> searches = action.getSearches();
//        if(searches != null) return searches;
//
//        Seed seed = getSeed(seedName);
//        searches = seed.getSearches();
//        if(searches != null) return searches;
//
//        return Collections.emptyList();
//    }
//
//    public List<String> getOrders(String seedName, RequestMethod method, String actionName) {
//        return SeedKit.getOrders(getSeed(seedName), method, actionName);
//    }
//
//    public List<String> getOrders(RequestMethod method, String actionName) {
//        Action action = getAction(method, actionName);
//        if(action == null) {
//            throw new RuntimeException(String.format("【%s】不存在", actionName));
//        }
//
//        return getOrders(action);
//    }
//
//    public List<String> getOrders(Action action) {
//        if(action == null) throw new RuntimeException("【action】不能为空");
//
//        String seedName = action.getSeedName();
//        if(StrUtil.isBlank(seedName)) return Collections.emptyList();
//
//        // 带路径的配置
//        List<String> orders = action.getOrders();
//        if(orders != null) return orders;
//
//        Seed seed = getSeed(seedName);
//        orders = seed.getOrders();
//        if(orders != null) return orders;
//
//        return Collections.emptyList();
//    }
//
//    public Map<String, Stat> getStats(String seedName, RequestMethod method, String actionName) {
//        return SeedKit.getStats(getSeed(seedName), method, actionName);
//    }
//
//    public Map<String, Stat> getStats(RequestMethod method, String actionName) {
//        Action action = getAction(method, actionName);
//        if(action == null) {
//            throw new RuntimeException(String.format("【%s】不存在", actionName));
//        }
//
//        return getStats(action);
//    }

//    public Map<String, Stat> getStats(Action action) {
//        if(action == null) throw new RuntimeException("【action】不能为空");
//
//        String seedName = action.getSeedName();
//        if(StrUtil.isBlank(seedName)) return Collections.emptyMap();
//
//        Map<String, Stat> stats = action.getStats();
//        if(stats != null) return stats;
//
//        Seed seed = getSeed(seedName);
//        stats = seed.getStats();
//        if(stats != null) return stats;
//
//        return Collections.emptyMap();
//    }

//    public boolean getCheckLogin(String seedName, RequestMethod method, String actionName) {
//        return getCheckLogin(getSeed(seedName), method, actionName);
//    }
//
//    public boolean getCheckLogin(Seed seed, RequestMethod method, String actionName) {
//        Action action = SeedKit.getAction(seed, method, actionName);
//        Boolean checkLogin = action.getCheckLogin();
//        if(checkLogin != null) return checkLogin;
//
//        checkLogin = seed.getCheckLogin();
//        if(checkLogin != null) return checkLogin;
//
//        return false;
//    }
//
//    public Map<String, Column> getColumns(String seedName) {
//        return getSeed(seedName).getColumns();
//    }
//
//    public Column getColumn(String seedName, String columnName) {
//        return getColumn(getSeed(seedName), columnName);
//    }
//
//    public Column getColumn(Seed seed, String columnName) {
//        columnName = StrUtil.toUnderlineCase(columnName);
//        Column column = seed.getColumns().get(columnName);
//        if(column == null) {
//            throw new RuntimeException(String.format("【%s】下【%s】不存在", seed.getName(), columnName));
//        }
//
//        return column;
//    }
//
//    public Map<String, Relation> getRelations(String seedName) {
//        return SeedKit.getRelations(getSeed(seedName));
//    }
//
//    public Relation getRelation(String seedName, String cross) {
//        return SeedKit.getRelations(getSeed(seedName)).get(cross);
//    }

//    public List<String> getKeywordColumns(String seedName) {
//        List<String> ret = new ArrayList<>();
//        Seed seed = getSeed(seedName);
//        List<String> keywordTypes = List.of("varchar", "tinytext", "text", "mediumtext", "longtext");
//        for(Column column : SeedKit.getColumns(seed).values()) {
//            ColumnType type = column.getType();
//            if(keywordTypes.contains(type.name())) ret.add(column.getName());
//        }
//
//        return ret;
//    }

//    public String getNameColumn(String seedName) {
//        return SeedKit.getNameColumn(getSeed(seedName));
//    }
//
//    public List<? extends OnSetListener> getOnSet(String seedName) {
//        return SeedKit.getOnSet(getSeed(seedName));
//    }
//
//    public List<? extends OnSaveListener> getOnSave(String seedName) {
//        return getOnSave(getSeed(seedName));
//    }
//
//    public List<? extends OnSaveListener> getOnSave(Seed seed) {
//        return seed.getOnSave();
//    }
//
//    public List<? extends OnUpdateListener> getOnUpdate(String seedName) {
//        return getOnUpdate(getSeed(seedName));
//    }
//
//    public List<? extends OnUpdateListener> getOnUpdate(Seed seed) {
//        return seed.getOnUpdate();
//    }
//
//    public SqlOp op(String seedName, String columnName) {
//        return SeedKit.op(getSeed(seedName), columnName);
//    }

//    public Map<String, Declared> buildDeclared(String seedName, String... declares) {
//        return buildDeclared(getSeed(seedName), declares);
//    }
//
//    public Map<String, Declared> buildDeclared(String seedName, List<String> declareList) {
//        return buildDeclared(getSeed(seedName), declareList);
//    }

//    public Map<String, Declared> buildDeclared(Seed seed, String... declares) {
//        if(declares == null || declares.length == 0) return Collections.emptyMap();
//
//        return buildDeclared(seed, Stream.of(declares).map(e -> StrUtil.isBlank(e) ? "" : e).distinct().toList());
//    }

//    public Map<String, Declared> buildDeclared(Seed seed, List<String> declareList) {
//        Map<String, Declared> ret = new HashMap<>();
//        for(String declare: declareList) buildDeclared(ret, seed, declare);
//
//        addExtraDeclared(seed, ret);
//        return ret;
//    }

//    public void buildDeclared(Map<String, Declared> container, Seed seed, String declare) {
//        declare = StrUtil.toUnderlineCase(declare);
//        Map<String, Column> columns = SeedKit.getColumns(seed);
//        if(declare.contains(".")) {
//            String[] items = StrKit.cutInTwo(declare, '.', false);
//            String cross = items[0];
//            String subDeclare = items[1];
//            Relation relation = SeedKit.getRelation(seed, cross);
//            Declared declared = container.get(cross);
//            if(declared == null) declared = new Declared(relation);
//            buildDeclared(declared, relation.targetSeed(), subDeclare);
//            container.put(cross, declared);
//        } else {
//            if("".equals(declare)) {
//                Declared declared = container.get(declare);
//                if(declared == null) container.put(declare, new Declared(PropertyType.none));
//            } else if("*".equals(declare)) {
//                Declared declared = container.get(declare);
//                if(declared == null) container.put(declare, new Declared(PropertyType.asterisk));
//            } else {
//                Column column = columns.get(declare);
//                if(column == null) {
//                    Relation relation = SeedKit.getRelation(seed, declare);
//                    Declared declared = container.get(declare);
//                    if(declared == null) declared = new Declared(relation);
//                    buildDeclared(declared, relation.targetSeed(), "");
//                    container.put(declare, declared);
//                } else {
//                    Declared declared = container.get(declare);
//                    if(declared == null) container.put(declare, new Declared(column));
//                }
//            }
//        }
//    }

//    /**
//     * 补充未声明的ID列
//     * @param seed
//     * @param declareds
//     */
//    private void addExtraDeclared(Seed seed, Map<String, Declared> declareds) {
//        Map<String, Column> columns = seed.getColumns();
//        Set<String> keySet = declareds.keySet();
//        if(!keySet.contains(Const.ID) && columns.get(Const.ID) != null) {
//            declareds.put(Const.ID, new Declared(columns.get(Const.ID)));
//        }
//        if(!keySet.contains(Const.VERSION) && columns.get(Const.VERSION) != null) {
//            declareds.put(Const.VERSION, new Declared(columns.get(Const.VERSION)));
//        }
//
//        for(Map.Entry<String, Declared> entry: declareds.entrySet()) {
//            Declared declared = entry.getValue();
//            PropertyType propertyType = declared.getType();
//            switch (propertyType) {
//                case hasOne, belongsTo, hasMany, habtm -> {
//                    Seed targetSeed = ((Relation) declared.getProperty()).targetSeed();
//                    addExtraDeclared(targetSeed, declared);
//                }
//            }
//        }
//    }

//    public Map<String, Searched> buildSearched(String seedName, String... searches) {
//        return buildSearched(getSeed(seedName), searches);
//    }
//
//    public Map<String, Searched> buildSearched(String seedName, List<String> searchList) {
//        return buildSearched(getSeed(seedName), searchList);
//    }

//    public Map<String, Searched> buildSearched(Seed seed, String... searches) {
//        return buildSearched(seed, List.of(searches));
//    }

//    public Map<String, Searched> buildSearched(Seed seed, List<String> searchList) {
//        Map<String, Searched> ret = new HashMap<>();
//        for(String search: searchList) buildSearched(ret, seed, search);
//
//        return ret;
//    }

//    public void buildSearched(Map<String, Searched> container, Seed seed, String search) {
//        String[] declareAndOpAndValues = StrKit.cutInTwo(search, '=', false);
//        String declareAndOp = declareAndOpAndValues[0];
//        String value = declareAndOpAndValues[1];
//
//        Map<String, Column> columns = SeedKit.getColumns(seed);
//        String[] declareAndOps = StrKit.cutInTwo(declareAndOp, '_', true);
//        String declare = StrUtil.toUnderlineCase(declareAndOps[0]);
//        String op = declareAndOps[1];
//        if(declare.contains(".")) {
//            String[] items = StrKit.cutInTwo(declare, '.', false);
//            String cross = items[0];
//            String subDeclareAndOp = items[1] + '_' + op;
//            String subSearch = StrUtil.isBlank(value) ? subDeclareAndOp : subDeclareAndOp + '=' + value;
//            Relation relation = SeedKit.getRelation(seed, cross);
//            Searched searched = container.get(cross);
//            if(searched == null) searched = new Searched(relation);
//            buildSearched(searched, relation.targetSeed(), subSearch);
//            container.put(cross, searched);
//        } else {
//            if("".equals(declare)) {
//                Searched searched = container.get(search);
//                if(searched == null) container.put(search, new Searched(PropertyType.none, value));
//            } else if("*".equals(declare)) {
//                Searched searched = container.get(search);
//                if(searched == null) container.put(search, new Searched(PropertyType.asterisk, value));
//            } else {
//                Column column = columns.get(declare);
//                if(column == null) {
//                    String subDeclareAndOp = "_" + op;
//                    String subSearch = StrUtil.isBlank(value) ? subDeclareAndOp : subDeclareAndOp + '=' + value;
//                    Relation relation = SeedKit.getRelation(seed, declare);
//                    Searched searched = container.get(declare);
//                    if(searched == null) searched = new Searched(relation);
//                    buildSearched(searched, relation.targetSeed(), subSearch);
//                    container.put(declare, searched);
//                } else {
//                    String key = String.format("%s_%s=%s", declare, op, value);
//                    Searched searched = container.get(key);
//                    if(searched == null) container.put(key, new Searched(column, value));
//                }
//            }
//        }
//    }

//    public Map<String, Ordered> buildOrdered(String seedName, String... orders) {
//        return buildOrdered(getSeed(seedName), orders);
//    }
//
//    public Map<String, Ordered> buildOrdered(String seedName, List<String> orderList) {
//        return buildOrdered(getSeed(seedName), orderList);
//    }

//    public Map<String, Ordered> buildOrdered(Seed seed, String... orders) {
//        return buildOrdered(seed, List.of(orders));
//    }

//    public Map<String, Ordered> buildOrdered(Seed seed, List<String> orderList) {
//        Map<String, Ordered> ret = new HashMap<>();
//        for(String search: orderList) buildOrdered(ret, seed, search);
//
//        return ret;
//    }

//    public void buildOrdered(Map<String, Ordered> container, Seed seed, String order) {
//        order = StrUtil.toUnderlineCase(order);
//        String[] declareAndValues = StrKit.cutInTwo(order, '=', false);
//        String declare = declareAndValues[0];
//        Direction value = StrUtil.isBlank(declareAndValues[1]) ? Direction.asc : Direction.valueOf(declareAndValues[1].toLowerCase());
//
//        Map<String, Column> columns = SeedKit.getColumns(seed);
//        if(declare.contains(".")) {
//            String[] items = StrKit.cutInTwo(declare, '.', false);
//            String cross = items[0];
//            String subDeclare = items[1];
//            String subOrder = subDeclare + '=' + value.name();
//            Relation relation = SeedKit.getRelation(seed, cross);
//            Ordered ordered = container.get(cross);
//            if(ordered == null) ordered = new Ordered(relation);
//            buildOrdered(ordered, relation.targetSeed(), subOrder);
//            container.put(cross, ordered);
//        } else {
//            if("".equals(declare)) {
//                Ordered ordered = container.get(declare);
//                if(ordered == null) container.put(declare, new Ordered(PropertyType.none, value));
//            } else if("*".equals(declare)) {
//                Ordered ordered = container.get(declare);
//                if(ordered == null) container.put(declare, new Ordered(PropertyType.asterisk, value));
//            } else {
//                Column column = columns.get(StrUtil.toUnderlineCase(declare));
//                if(column == null) {
//                    String subDeclare = "";
//                    String subOrder = subDeclare + '=' + value.name();
//                    Relation relation = SeedKit.getRelation(seed, declare);
//                    Ordered ordered = container.get(declare);
//                    if(ordered == null) ordered = new Ordered(relation);
//                    buildOrdered(ordered, relation.targetSeed(), subOrder);
//                    container.put(declare, ordered);
//                } else {
//                    Ordered ordered = container.get(declare);
//                    if(ordered == null) container.put(declare, new Ordered(column, value));
//                }
//            }
//        }
//    }

//    public List<List<List<Map<String, Searched>>>> getDataPermised(Seed seed, List<List<List<List<String>>>> dataPermis) {
//        List<List<List<Map<String, Searched>>>> ret = new ArrayList<>();
//        if(dataPermis == null) return ret;
//
//        for(List<List<List<String>>> listlistlist: dataPermis) {
//            List<List<Map<String, Searched>>> retlistlist = new ArrayList<>();
//            for(List<List<String>> listList: listlistlist) {
//                List<Map<String, Searched>> retlist = new ArrayList<>();
//                for(List<String> list: listList) {
//                    retlist.add(buildSearched(seed, list));
//                }
//                retlistlist.add(retlist);
//            }
//            ret.add(retlistlist);
//        }
//
//        return ret;
//    }
}
